function mxCellState(view, cell, style)
{
	this.view = view;
	this.cell = cell;
	this.style = style;
	this.origin = new mxPoint();
	this.absoluteOffset = new mxPoint();
};
mxCellState.prototype = new mxRectangle();
mxCellState.prototype.constructor = mxCellState;
mxCellState.prototype.view = null;
mxCellState.prototype.cell = null;
mxCellState.prototype.style = null;
mxCellState.prototype.invalid = true;
mxCellState.prototype.orderChanged = null;
mxCellState.prototype.origin = null;
mxCellState.prototype.absolutePoints = null;
mxCellState.prototype.absoluteOffset = null;
mxCellState.prototype.terminalDistance = 0;
mxCellState.prototype.length = 0;
mxCellState.prototype.segments = null;
mxCellState.prototype.shape = null;
mxCellState.prototype.text = null;
mxCellState.prototype.getPerimeterBounds = function(border)
{
	border = border || 0;
	var bounds = new mxRectangle(this.x, this.y, this.width, this.height);

	if (border != 0)
	{
		bounds.grow(border);
	}
	return bounds;
};
mxCellState.prototype.setAbsoluteTerminalPoint = function(point, isSource)
{
	if (isSource)
	{
		if (this.absolutePoints == null)
		{
			this.absolutePoints = [];
		}

		if (this.absolutePoints.length == 0)
		{
			this.absolutePoints.push(point);
		}
		else
		{
			this.absolutePoints[0] = point;
		}
	}
	else
	{
		if (this.absolutePoints == null)
		{
			this.absolutePoints = [];
			this.absolutePoints.push(null);
			this.absolutePoints.push(point);
		}
		else if (this.absolutePoints.length == 1)
		{
			this.absolutePoints.push(point);
		}
		else
		{
			this.absolutePoints[this.absolutePoints.length - 1] = point;
		}
	}
};
mxCellState.prototype.destroy = function()
{
	this.view.graph.cellRenderer.destroy(this);
	this.view.graph.destroyHandler(this);
};
mxCellState.prototype.clone = function()
{
	var clone = new mxCellState(this.view, this.cell, this.style);

	if (this.absolutePoints != null)
	{
		clone.absolutePoints = [];

		for (i = 0; i < this.absolutePoints.length; i++)
		{
			clone.absolutePoints.push(this.absolutePoints[i].clone());
		}
	}

	if (this.origin != null)
	{
		clone.origin = this.origin.clone();
	}

	if (this.absoluteOffset != null)
	{
		clone.absoluteOffset = this.absoluteOffset.clone();
	}

	if (this.sourcePoint != null)
	{
		clone.sourcePoint = this.sourcePoint.clone();
	}

	if (this.boundingBox != null)
	{
		clone.boundingBox = this.boundingBox.clone();
	}
	clone.terminalDistance = this.terminalDistance;
	clone.segments = this.segments;
	clone.length = this.length;
	clone.x = this.x;
	clone.y = this.y;
	clone.width = this.width;
	clone.height = this.height;
	return clone;
};

function mxTemporaryCellStates(view, scale, cells)
{
	this.view = view;
	scale = (scale != null) ? scale : 1;
	this.oldBounds = view.getGraphBounds();
	this.oldStates = view.getStates();
	this.oldScale = view.getScale();
	view.setStates(new mxDictionary());
	view.setScale(scale);

	if (cells != null)
	{
		var state = view.createState(new mxCell());

		for (var i = 0; i < cells.length; i++)
		{
			view.validateBounds(state, cells[i]);
		}
		var minX = null;
		var minY = null;
		var maxX = 0;
		var maxY = 0;

		for (var i = 0; i < cells.length; i++)
		{
			var bounds = view.validatePoints(state, cells[i]);
			minX = (minX != null) ? Math.min(minX, bounds.x) : bounds.x;
			minY = (minY != null) ? Math.min(minY, bounds.y) : bounds.y;
			maxX = Math.max(maxX, bounds.x + bounds.width);
			maxY = Math.max(maxY, bounds.y + bounds.height);
		}

		if (minX != null && minY != null)
		{
			view.setGraphBounds(new mxRectangle(minX, minY, maxX - minX, maxY - minY));
		}
	}
};
mxTemporaryCellStates.prototype.view = null;
mxTemporaryCellStates.prototype.oldStates = null;
mxTemporaryCellStates.prototype.oldBounds = null;
mxTemporaryCellStates.prototype.oldScale = null;
mxTemporaryCellStates.prototype.destroy = function()
{
	this.view.setScale(this.oldScale);
	this.view.setStates(this.oldStates);
	this.view.setGraphBounds(this.oldBounds);
};